---
title: UserAccess
summary: API reference for UserAccess.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-08-21
library: SAIF.Application
reference_type: embedded
---

# UserAccess

`UserAccess` is the abstract, per-instance authorization-decision cache extended by domain access classes such as `SAIF.Application.Claim/ClaimUserAccess`. It binds to a `clsSecurityPrincipal` via `SetPrincipal` and memoizes each resource name's `IsAuthorized` result in a case-insensitive `SortedList(Of String, Boolean)`, so repeated AD resource checks during a single request do not re-query the security service ([BR-APP-004](../../business-rules.md#br-app-004-ad-resource-authorization-is-cached-per-instance)). It carries no knowledge of any specific AD resource name — resource names are supplied entirely by callers and forwarded verbatim to the framework principal.

## Purpose
- Provides the single authorization-decision call site in this library: `HasAccess` is the only member that actually asks `clsSecurityPrincipal.IsAuthorized` for a decision.
- Caches each decision per instance, keyed on the lower-cased resource name, so a mid-session AD group change is not observed until a new instance is created ([BR-APP-004](../../business-rules.md#br-app-004-ad-resource-authorization-is-cached-per-instance)).
- Supplies a cache-warming entry point (`CheckAccess`) for callers that want to pre-evaluate several resource names in one call.

## Context
- Namespace: `SAIF.Application`
- Assembly/package: `SAIF.Application` (embedded, ProjectReference)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| `CheckAccess` | `Public Sub (ParamArray inResourceName As String())` | Pre-evaluates and caches authorization for a set of AD resource names in one call; the per-resource result is discarded, so the method's only effect is populating the cache. |
| `HasAccess` | `Public Function (inResourceName As String) As Boolean` | Returns the cached authorization decision, or on first request calls `clsSecurityPrincipal.IsAuthorized(inResourceName)` and caches the result under the lower-cased resource name ([BR-APP-004](../../business-rules.md#br-app-004-ad-resource-authorization-is-cached-per-instance)). |

### Protected members (available to derived access classes)
| Member | Signature | Purpose |
| --- | --- | --- |
| `SetPrincipal` | `Protected Sub (inPrincipal As clsSecurityPrincipal)` | Injects the identity whose authorizations are evaluated; derived classes must call this before `HasAccess`. |

## Behavioral notes
- `m_Principal` has no default; calling `HasAccess` before `SetPrincipal` throws a `NullReferenceException` rather than failing via an explicit deny.**
- `CheckAccess` loops the supplied names calling `HasAccess` on each, but the loop variable is overwritten each iteration and then discarded, so the method returns no information to the caller — it is a cache warm-up only.
- The framework appends the environment suffix (`Resource` / `TestResource`) to the resource name inside `clsSecurityPrincipal.IsAuthorized`, not in this class.*

## Constraints and usage notes
- The class is `MustInherit`; it must be extended by a domain access class (e.g. `ClaimUserAccess`) that calls `SetPrincipal` and supplies concrete resource names.
- Resource-name matching is case-insensitive because both the cache key and the `HasAccess` argument are lower-cased before comparison.

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with `**` could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Application/UserAccess.vb`
- `SAIF.Application.Claim/ClaimUserAccess.vb`
